﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;

namespace ConsoleApp
{
    //线程池，预先创建的线程，异步默认使用线程池
    public class _Thread
    {
        static void Main1(string[] args)
        {
            int? toalcount = 100_000;
            int count = 0;
            //object _lock = new object();
            Thread thread1 = new Thread(ThreadMethod) ;
            Thread thread2 = new Thread(ThreadMethod) ;

            thread1.Start();
            thread2.Start();

            thread1.Join();
            thread2.Join();
            
            Console.WriteLine($"Count :{count}");
            
            void ThreadMethod()
            {
                for (int i = 0; i < toalcount; i++)
                {
                    //加锁操作
                    //lock (_lock)
                    //{
                    //    count++;
                    //}
                    //原子操作
                    Interlocked.Increment(ref count);
                }
            }
        }
    }
    public class _Thread2
    {
        static void Main1(string[] args) 
        {
            //var queue = new Queue<int>();
            var queue = new ConcurrentQueue<int>();
            object _lock = new object();
            var producer = new Thread(AddNumber);
            var consumer1 = new Thread(ReadNumber1);
            var consumer2 = new Thread(ReadNumber1);

            producer.Start();
            consumer1.Start();
            consumer2.Start();  
            producer.Join();
            consumer1.Interrupt();
            consumer2.Interrupt();
            consumer1.Join();
            consumer2.Join();

            void AddNumber()
            {
                for(int i = 0; i < 20; i++)
                {
                    Thread.Sleep(10);
                    queue.Enqueue(i);

                }
            }
            void ReadNumber1()
            {
                try
                {
                    while (true)
                    {
                        /*lock (_lock)//加锁操作，保证线程安全，其他方法，①同步机制，②原子操作
                        {
                            if (queue.TryDequeue(out var i))
                            {
                                Console.WriteLine(i);
                                Thread.Sleep(1);
                            }
                        }*/
                        if (queue.TryDequeue(out var i))
                        {
                            Console.WriteLine(i);
                        }
                        Thread.Sleep(1);
                    }
                }
                catch (ThreadInterruptedException) 
                {
                    Console.WriteLine("Thread interrupted");
                }
                
            }
            
        }
    }
    public class _Thread3
    {
        //线程的终止
        static void Main1(string[] args)
        {
            bool run = true;
            Console.WriteLine("Run in Main Thread");
            var th = new Thread((obj) =>
            {
                try
                {
                    Console.WriteLine(obj);
                    while (run)
                    {
                        /*for (int i = 0; i < 20; i++)
                        {
                            Thread.Sleep(200);
                            Console.WriteLine("Thread is still runing");
                        }*/
                        Thread.Sleep(1);
                    }
                    
                }
                catch (ThreadInterruptedException) 
                {
                    Console.WriteLine("interrupted");
                }
                finally
                {
                    Console.WriteLine("Finished");
                }
            });
            th.Start(123);
            Thread.Sleep(1000);
            th.Interrupt();
            //th.Join();
            Console.WriteLine("Done");
        }
    }
    //线程安全同步机制
    //lock&Monitor,Mutex,Semaphore,WaitHandle,ReadWriterLock
    public class _Thread4 
    {
        static void Main1(string[] args) 
        {
            var input = Enumerable.Range(1,20).ToArray();
            var sw = Stopwatch.StartNew();
            var semephore = new Semaphore(3,3);
            //var outputs = new int[input.Length];
            var outputs = input.AsParallel().AsOrdered().Select(HeayJob).ToArray();
            //for (int i = 0; i < input.Length; i++) 
            //{
            //    outputs[i] = HeayJob(input[i]);
            //}
            Console.WriteLine("Outputs:");
            Console.WriteLine(string.Join(",",outputs));
            Console.WriteLine($"Elapsed time :{sw.ElapsedMilliseconds}ms");
            semephore.Dispose();
            int HeayJob(int input)
            {
                semephore.WaitOne();//等待
                //Console.WriteLine(input * input);
                Thread.Sleep(300);
                semephore.Release();
                return input * input;
            }
            
        }
    }
    //取消操作
    public class _Thread5
    {
        static void Main1(string[] args) 
        {
            var cts = new CancellationTokenSource();
            var token = cts.Token;
            var sw = Stopwatch.StartNew();
            async void Program()
            {
                await Task.Delay(5000, token);
                Console.WriteLine($"Task completed in {sw}");
            }
        }
        static async void Program()
        {
            var cts = new CancellationTokenSource();
            var token = cts.Token;
            var sw = Stopwatch.StartNew();

            await Task.Delay(5000, token);
            Console.WriteLine($"Task completed in {sw}");
        }
        
    }


}
